#include<iostream>
#include<string>
#include<boost/filesystem/operations.hpp>
#include<iostream>
namespace bfs = boost::filesystem;

using namespace std;

bfs::path gxSourcePath;
bfs::path gxTargetPath;

int createShadowDir
	(
	bfs::path xSourceDir,
	bfs::path xSourceDirBase,
	bfs::path xTargetDirBase
	)
{
	std::string sSourceDir = xSourceDir.directory_string();
	std::string sSourceDirBase=  xSourceDirBase.directory_string();
	std::string sTargetDirBase= xTargetDirBase.directory_string();
	std::string sShadowDir;

	if(sSourceDir == sTargetDirBase)
	{
		//Otherwise recursive directories created if TargetDirBase is within SourceDirBase
		return 1;
	}

	sSourceDir.erase(0,sSourceDirBase.length()+1); //+1 since starting with / also absolute path!
	
	bfs::path xShadowDir = complete(bfs::path(sSourceDir), xTargetDirBase);


	cout<<"Creating..."<<xShadowDir<<endl;	
	bfs::create_directory(xShadowDir);

	return 0;

}

void traverseDirectory(const bfs::path& xPath, bool bRecurse=true)
{
	
	//cout<<"In directory:"<<xPath.native_file_string()<<"\n";
	
	bfs::directory_iterator xLooper(xPath), xLoopEnd;
	
	for(; xLooper != xLoopEnd; ++xLooper)
	{
		try {
			if(bfs::is_directory(*xLooper))
			{
				//cout<<*xLooper<<endl;
				//if(gxTargetPath == *xLooper)

				if( 0!=createShadowDir(*xLooper,gxSourcePath,gxTargetPath))
				{
					continue;
				}

				if(bRecurse)
				{
					bfs::path xNewDir(*xLooper);
					traverseDirectory(xNewDir, bRecurse);
					
				}
			}
		} catch(const std::exception & ex) {
			std::cerr<<xLooper->leaf() <<": " <<ex.what() <<std::endl;
		}
	}  
	
}  



int main(int argc, char** argv)
{
	
	if(argc<2)
	{
		cerr<<"No destination provided";
		return 1;
	}

	gxSourcePath = bfs::complete(bfs::path(argv[1], bfs::native));
	if( !bfs::exists(gxSourcePath) )
	{
		cerr<<gxSourcePath.leaf()<<" does not exist.\n";
		return 2;
	}

	if( !bfs::is_directory(gxSourcePath))
	{
		cerr<<gxSourcePath.leaf()<<" is not a directory.\n";
		return 3;
	}

	gxTargetPath = bfs::complete(bfs::path("neptuner"),gxSourcePath ) ;
	cout<<"New:"<<gxTargetPath<<endl;

	create_directory(gxTargetPath);

	traverseDirectory(gxSourcePath);
	//bfs::path xPath("C:/Music");

	//
	//std::cout<<xInitialPath;
	//
	//
	//traverseDirectory(xPath,true);

	////int n;
	////std::cin>>n;
	cout<<gxSourcePath.leaf()<<" is a directory. Success!";
	return 0;
}